package id.co.shuba.spamobile.task;

import id.co.shuba.spamobile.App;
import id.co.shuba.spamobile.util.Str;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.Toast;

public class DownloadUpdateTask extends AsyncTask<String, Integer, AsyncTaskResult<String>> {
	static final int BUFF_SIZE = 1024 * 4;
	static final int MAX_TRY = 5;
	private ProgressBar _bar;	
	private int mStartByte;
	private int mEndByte;
	private String eTag;
	private boolean error;
	private int nTry;
	
	public DownloadUpdateTask(ProgressBar bar) {
		_bar = bar;		
	}	
	
	@Override
	protected void onPreExecute() {	
		super.onPreExecute();		
		
		_bar.setProgress(0);
	}
	
	public void setProgressBar(ProgressBar bar) {
		_bar = bar;
	}
	
    @Override
    protected AsyncTaskResult<String> doInBackground(String... sUrl) {
        try {        	        	               	                        
            File spaDir = new File(Environment.getExternalStorageDirectory(), "spamobile");
            if (!spaDir.exists())
            	spaDir.mkdirs();
                        
            File file = new File(spaDir, "update.apk");
            if (file.exists())
            	file.delete();            	            
            
            String url = sUrl[0];
            while (!isCancelled()) {    			
    			if (nTry >= MAX_TRY)
    				throw new Exception("Download Error");    				    			
    			
    			try {
    				doDownload(url);
    			} catch (Exception e) {
    				Log.e("Download", e.getMessage(), e);
    				nTry++;
    			}
    		}
            
            return new AsyncTaskResult<String>(file.getPath());
        } catch (Exception e) {
        	e.printStackTrace();
        	return new AsyncTaskResult<String>(e);
        }        
    }
    
    private void doDownload(String mUrl) throws IOException {
		BufferedInputStream in = null;
		RandomAccessFile raf = null;					
		
		try {
			URL url = new URL(mUrl);
			// open Http connection to URL
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();											
			if (!Str.isNullOrEmpty(eTag))
				conn.setRequestProperty("If-Match", eTag);
			
			// set the range of byte to download
			String byteRange = mStartByte + "-" + mEndByte;				
			conn.setRequestProperty("Range", "bytes=" + byteRange);
			System.out.println("bytes=" + byteRange);
			
			// connect to server
			conn.connect();
			

			String tag = conn.getHeaderField("ETag");
			if (!Str.isNullOrEmpty(tag))					
					eTag = tag;						
																						
			// Make sure the response code is in the 200 range.
            if (conn.getResponseCode() / 100 != 2) {
            	error = true;
            	return;
            }			
			
			in = new BufferedInputStream(conn.getInputStream());
			
			raf = new RandomAccessFile("update.apk", "rw");
			raf.seek(mStartByte);
						
			byte data[] = new byte[BUFF_SIZE];
			int numRead;
			while(!isCancelled() && ((numRead = in.read(data,0,BUFF_SIZE)) != -1))
			{													
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				// write to buffer
				raf.write(data,0,numRead);
				// increase the startByte for resume later
				mStartByte += numRead;					
				// increase the downloaded size											
			}						
		} catch (IOException e) {
			//error();
			throw e;
		} finally {
			if (raf != null) {
				try {
					raf.close();
				} catch (IOException e) {}
			}
			
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {}
			}
		}			
	}	
    
    @Override
    protected void onProgressUpdate(Integer... values) {    
    	super.onProgressUpdate(values);
    	
    	if (_bar != null)
    		_bar.setProgress(values[0]);
    }
    
    @Override
    protected void onPostExecute(AsyncTaskResult<String> result) {    	
    	
    	Context ctx = _bar.getContext();
    	if (result.getError() != null) {
    		Toast.makeText(_bar.getContext(),
    				result.getError().getMessage(),Toast.LENGTH_LONG).show();
    		return;
    	}
    	
    	Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(new File(result.getResult())),
        		"application/vnd.android.package-archive");        
        ctx.startActivity(intent);
    }
}
